#!/usr/bin/python
# -*- coding: utf-8 -*-
"""数据库操作基类
"""
from urllib import quote_plus

from former_project.common_logic import cache as _data_cache
from former_project.common_logic.utility.singleton import Singleton
from former_project.common_logic.db import ConnectionPool

class DBOperator(Singleton):
    """数据库操作基类"""
    
    CACHE_TIME = 1800 # 30分钟超时
    CACHE_KEY_PREFIX = ''
    cache = _data_cache
    SOLR_TYPE = None
    
    def _format(self, key):
        if self.CACHE_KEY_PREFIX:
            key = self.CACHE_KEY_PREFIX + key
        return key.encode('utf-8')
    
    def set_cache(self, key, val, cache_time=CACHE_TIME):
        self.cache.set(self._format(key), val, cache_time)
        
    def set_multi_cache(self, mapping, cache_time=CACHE_TIME):
        self.cache.set_multi(mapping, cache_time, 
                             key_prefix=self.CACHE_KEY_PREFIX)
    
    def get_cache(self, key):
        return self.cache.get(self._format(key))
    
    def get_multi_cache(self, keys):
        """return values list"""
        rs = self.cache.get_multi(keys, key_prefix=self.CACHE_KEY_PREFIX)
        return rs.values()
    
    def delete_cache(self, key):
        return self.cache.delete(self._format(key))
    
    def delete_multi_cache(self, keys):
        return self.cache.delete_multi(keys, key_prefix=self.CACHE_KEY_PREFIX)
    
    def cursor(self):
        return ConnectionPool.cursor()
    
    def _get_datas(self, keys):
        cache_datas = self.get_multi_cache(keys)
        if len(cache_datas) == len(keys):
            return cache_datas
        if isinstance(keys, tuple):
            nofounds = list(keys)
        else:
            nofounds = keys
        if cache_datas:
            for i in cache_datas:
                k = self.get_data_key(i)
                if k in nofounds:
                    nofounds.remove(k)
        rs = self.get_datas_by_keys(nofounds)
        if rs:
            maping = {}
            for r in rs:
                maping[self.get_data_key(r)] = r
            self.set_multi_cache(maping)
        if cache_datas:
            return list(rs) + cache_datas
        else:
            return rs
    
    def get_data_key(self, r):
        """返回记录的主键值
        child must be implement this method for search"""
        raise NotImplementedError()
    
    def get_datas_by_keys(self, keys):
        """child must be implement this method for search"""
        raise NotImplementedError()
